home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr26
/
4utils73.zip
/
DESCRIPT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-05-01
|
12KB
|
422 lines
UNIT DescriptionHandling;
{$L+,X+,V-}
(* ----------------------------------------------------------------------
Part of 4DESC - A Simple 4DOS File Description Editor
and 4FF - 4DOS File Finder
David Frey, & Tom Bowden
Urdorferstrasse 30 1575 Canberra Drive
8952 Schlieren ZH Stone Mountain, GA 30088-3629
Switzerland USA
Code created using Turbo Pascal 7.0 (c) Borland International 1992
DISCLAIMER: This unit is freeware: you are allowed to use, copy
and change it free of charge, but you may not sell or hire
this part of 4DESC. The copyright remains in our hands.
If you make any (considerable) changes to the source code,
please let us know. (send a copy or a listing).
We would like to see what you have done.
We, David Frey and Tom Bowden, the authors, provide absolutely
no warranty of any kind. The user of this software takes the
entire risk of damages, failures, data losses or other
incidents.
This unit stores/retrieves the file data and descriptions by using
a TCollection (a Turbo Vision Object).
----------------------------------------------------------------------- *)
INTERFACE USES Objects, Dos, StringDateHandling;
CONST MaxDescLen = 42;
DirSize = ' <DIR> ';
TYPE NameExtStr = STRING[1+8+1+3];
SizeStr = STRING[9];
DescStr = STRING[MaxDescLen];
ProgInfo = STRING;
SortKeyStr = STRING[14];
VAR DescLong : BOOLEAN;
TYPE PFileData = ^TFileData;
TFileData = OBJECT(TObject)
IsADir : BOOLEAN;
Name : PString; (* ^NameExtStr; *)
Size : PString; (* ^SizeStr; *)
Date : PString; (* ^DateStr; *)
Time : PString; (* ^TimeStr; *)
ProgInfo : PString; (* ^STRING; *)
Desc : PString; (* ^DescStr; *)
SortKey : PString; (* ^SortKeyStr; *)
CONSTRUCTOR Init(Search: SearchRec);
DESTRUCTOR Done; VIRTUAL;
PROCEDURE AssignName(AName: NameExtStr);
PROCEDURE AssignDesc(ADesc: DescStr);
PROCEDURE AssignProgInfo(AProgInfo: STRING);
FUNCTION GetDesc: DescStr;
FUNCTION GetSize: SizeStr;
FUNCTION GetName: NameExtStr;
FUNCTION GetProgInfo: STRING;
FUNCTION FormatDescription: STRING;
END;
CONST ListOK = 0;
ListTooManyFiles = 1;
ListOutOfMem = 2;
TYPE PFileList = ^TFileList;
TFileList = OBJECT(TSortedCollection)
Status : BYTE;
MaxFileLimit: INTEGER;
CONSTRUCTOR Init(Path: PathStr);
FUNCTION KeyOf(Item: POINTER): POINTER; VIRTUAL;
FUNCTION Compare(key1,key2: POINTER): INTEGER; VIRTUAL;
END;
VAR FileList : PFileList;
FUNCTION NILCheck(APtr: POINTER): POINTER;
IMPLEMENTATION USES Memory, DisplayKeyboardAndCursor, Drivers;
(* Allocate a 2KB text buffer for faster reads of DESCRIPT.ION *)
VAR Buffer: ARRAY[1..2048] OF CHAR;
{$F+}
FUNCTION HeapFunc(Size: WORD): INTEGER;
BEGIN
HeapFunc := 1; (* Return nil if out of heap *)
END;
{$F-}
FUNCTION NILCheck(APtr: POINTER): POINTER;
(* Aborts when a NIL pointer has been detected. This prevents
deferencing a NIL pointer, which could be catastrophic
(spontaneous rebooting etc.) *)
BEGIN
IF APtr = NIL THEN Abort('NIL Pointer detected!')
ELSE NILCheck := APtr;
END;
CONSTRUCTOR TFileData.Init(Search: SearchRec);
(* Constructor method. Constructs a FileData "object" on the heap
a fills in the appropriate values. *)
VAR TimeRec : DateTime;
s : STRING;
c : CHAR;
BEGIN
TObject.Init;
UnpackTime(Search.Time,TimeRec);
Name := NIL;
Date := NIL; Date := NewStr(FormDate(TimeRec));
Time := NIL; Time := NewStr(FormTime(TimeRec));
ProgInfo := NIL;
Desc := NIL;
SortKey := NIL;
IsADir := (Search.Attr AND Directory = Directory);
IF IsADir THEN
BEGIN
s := DirSize;
c := '0';
UpString(Search.Name);
END
ELSE
BEGIN
IF FullSize THEN Str(Search.Size:8,s)
ELSE s := FormattedLongIntStr(Search.Size DIV 1024,7)+'K';
c := '1';
END;
Size := NewStr(s);
Name := NewStr(Search.Name);
SortKey := NewStr(c + Search.Name);
(* Force directories ahead of files in sorted display. *)
END;
DESTRUCTOR TFileData.Done;
(* Removes a FileData object from the heap. *)
BEGIN
DisposeStr(Date); Date := NIL;
DisposeStr(Time); Time := NIL;
DisposeStr(ProgInfo); ProgInfo := NIL;
DisposeStr(Desc); Desc := NIL;
DisposeStr(Name); Name := NIL;
DisposeStr(Size); Size := NIL;
DisposeStr(SortKey); SortKey := NIL;
TObject.Done;
END;
PROCEDURE TFileData.AssignName(AName: NameExtStr);
BEGIN
IF Name <> NIL THEN
BEGIN DisposeStr(Name); Name := NIL; END;
Name := NewStr(AName);
IF (AName <> '') AND (Name = NIL) THEN
Abort('AssignName: NIL Pointer detected!')
END;
PROCEDURE TFileData.AssignDesc(ADesc: DescStr);
BEGIN
IF Desc <> NIL THEN
BEGIN DisposeStr(Desc); Desc := NIL; END;
Desc := NewStr(ADesc);
IF (ADesc <> '') AND (Desc = NIL) THEN
Abort('AssignDesc: NIL Pointer detected!')
END;
PROCEDURE TFileData.AssignProgInfo(AProgInfo: STRING);
BEGIN
IF ProgInfo <> NIL THEN
BEGIN DisposeStr(ProgInfo); ProgInfo := NIL; END;
ProgInfo := NewStr(AProgInfo);
IF (AProgInfo <> '') AND (ProgInfo = NIL) THEN
Abort('AssignProgInfo: NIL Pointer detected!')
END;
FUNCTION TFileData.GetDesc: DescStr;
BEGIN
IF Desc <> NIL THEN GetDesc := Desc^
ELSE GetDesc := '';
END;
FUNCTION TFileData.GetSize: SizeStr;
BEGIN
IF Size <> NIL THEN GetSize := Size^
ELSE GetSize := '';
END;
FUNCTION TFileData.GetName: NameExtStr;
BEGIN
IF Name <> NIL THEN GetName := Name^
ELSE GetName := '';
END;
FUNCTION TFileData.GetProgInfo: STRING;
BEGIN
IF ProgInfo <> NIL THEN GetProgInfo := ProgInfo^
ELSE GetProgInfo := '';
END;
FUNCTION TFileData.FormatDescription: STRING;
VAR ia : ARRAY[0..4] OF PString;
s : STRING;
BEGIN
ia[0] := Name;
ia[1] := Size;
ia[2] := Date;
ia[3] := Time;
ia[4] := Desc;
FormatStr(s,' %-12s%s %s %s %s',ia);
FormatDescription := s;
END;
CONSTRUCTOR TFileList.Init(Path: PathStr);
(* Build a list of FileData objects by inserting the directory entries
in a TSortedCollection. *)
CONST CR = #13;
LF = #10;
EOFMark = #26;
VAR DescFileExists : BOOLEAN;
DescFound : BOOLEAN;
DescFile : TEXT;
DescLine : STRING;
DescName : NameExtStr;
DescStart : BYTE;
DescEnd : BYTE;
Desc : STRING;
ProgInfo : STRING;
sr : SearchRec;
ListEntry : PFileData;
mfl : LONGINT;
c : ARRAY[0..1] OF CHAR;
l : BYTE;
Index : INTEGER;
Key : PString;
SKeyName : SortKeyStr;
(***********************************************
FUNCTION HasDescription(AnEntry: PFileData): BOOLEAN; FAR;
BEGIN
IF AnEntry = NIL THEN HasDescription := FALSE
ELSE HasDescription := (AnEntry^.GetName = DescName);
END;
************************************************)
PROCEDURE DescSearch;
BEGIN
Key := @SKeyName;
IF Search(Key,Index) THEN
BEGIN
DescEnd := Pos(#4,DescLine);
IF DescEnd = 0 THEN DescEnd := Length(DescLine)+1;
IF (DescEnd-1) - (DescStart+1) > MaxDescLen THEN DescLong := TRUE;
Desc := Copy(DescLine,DescStart+1,DescEnd-1);
StripLeadingSpaces(Desc);
StripTrailingSpaces(Desc);
ListEntry := At(Index);
ListEntry^.AssignDesc(Desc);
ProgInfo := Copy(DescLine,DescEnd,255);
ListEntry^.AssignProgInfo(ProgInfo);
END;
END;
PROCEDURE BeautifyEntries(AnEntry: PFileData); FAR;
VAR s : NameExtStr;
p : BYTE;
BEGIN
IF (AnEntry <> NIL) AND NOT AnEntry^.IsADir THEN
WITH AnEntry^ DO
BEGIN
s := GetName;
p := Pos('.',s);
IF p > 0 THEN
BEGIN
WHILE NOT NotLeftJust AND (p <> 9) AND (Length(s) < 13) DO
BEGIN
System.Insert(' ',s,p);
p := Pos('.',s);
END;
AssignName(s);
END;
END; (* with *)
END;
BEGIN
mfl := (MemAvail-2048) DIV SizeOf(POINTER);
IF mfl > MaxCollectionSize THEN MaxFileLimit := MaxCollectionSize
ELSE MaxFileLimit := INTEGER(mfl);
TCollection.Init(MaxFileLimit,0); Status := ListOK;
FindFirst('*.*',ReadOnly+Archive+Directory+BYTE(UseHidden)*Hidden+SysFile, sr);
WHILE (DosError = 0) AND (Status = ListOK) AND (Count < MaxCollectionSize) DO
BEGIN
DownString(sr.Name);
IF MemAvail < SizeOf(TFileData) THEN Status := ListOutOfMem
ELSE
BEGIN
ListEntry := NIL; ListEntry := New(PFileData,Init(sr));
IF ListEntry <> NIL THEN Insert(ListEntry)
ELSE Status := ListOutOfMem;
END;
FindNext(sr);
END; (* while *)
IF Count = MaxFileLimit THEN Status := ListTooManyFiles;
FindFirst('DESCRIPT.ION',Hidden + Archive,sr);
DescFileExists := (DosError = 0);
IF DescFileExists THEN
BEGIN
{$I-}
Assign(DescFile,'DESCRIPT.ION');
SetTextBuf(DescFile,Buffer);
Reset(DescFile);
{$I+}
REPEAT
DescLine := '';
c[0] := #0;
REPEAT
c[1] := c[0];
Read(DescFile,c[0]);
DescLine := DescLine + c[0];
UNTIL ((c[0] = CR) AND (c[1] = LF)) OR
(c[1] = CR) OR
(c[1] = LF) OR
(c[1] = EOFMark);
l := Length(DescLine);
WHILE (DescLine[l] = CR) OR
(DescLine[l] = LF) OR
(DescLine[l] = EOFMark) DO
BEGIN
System.Delete(DescLine,l,1);
l := Length(DescLine);
END;
DescStart := Pos(' ',DescLine);
IF DescStart = 0 THEN DescStart := Length(DescLine)+1;
DescName := Copy(DescLine,1,DescStart-1);
DownString(DescName);
SKeyName := '1' + DescName;
DescSearch; (* File name search *)
UpString(DescName);
SKeyName := '0' + DescName;
DescSearch; (* Directory name search *)
UNTIL Eof(DescFile);
{$I-}
Close(DescFile);
{$I+}
END;
ForEach(@BeautifyEntries);
END; (* TFileList.Init *)
FUNCTION TFileList.KeyOf(Item: POINTER): POINTER;
BEGIN
KeyOf := PFileData(Item)^.SortKey;
END; (* TFileList..KeyOf *)
FUNCTION TFileList.Compare(key1,key2: POINTER): INTEGER;
(* This function tells the sorted collection how to sort its members.
(by Name, directories first) *)
BEGIN
IF PString(key1)^ = PString(key2)^ then Compare := 0
ELSE
IF PString(key1)^ < PString(key2)^ then Compare := -1
ELSE Compare := +1;
END; (* TFileList.Compare *)
BEGIN
FileList := NIL; (* never leave a Pointer uninitialized ! *)
END.